from fastapi import APIRouter, Depends, HTTPException, Body
from pydantic import BaseModel, Field
from datetime import datetime
from typing import List, Dict, Any
import json

from api.common import get_document_manager, get_db
from db_utils import Database
from db.model_loader import model_loader

router = APIRouter(prefix="/chat", tags=["对话"])


# Pydantic模型定义
class MessageCreate(BaseModel):
    content: str = Field(..., min_length=1, description="消息内容")


class MessageResponse(BaseModel):
    id: int
    role: str
    content: str
    created_at: str

    class Config:
        from_attributes = True


class ConversationCreate(BaseModel):
    title: str | None = Field(None, max_length=255, description="对话标题")


class ConversationResponse(BaseModel):
    id: int
    title: str
    created_at: str
    updated_at: str

    class Config:
        from_attributes = True


@router.get("/document/{document_id}", response_model=List[ConversationResponse])
async def get_conversations_by_document(
    document_id: int,
    doc_manager=Depends(get_document_manager),
):
    """获取指定文档的所有对话"""
    try:
        session = doc_manager.db.connect()
        # 检查文档是否存在
        document = doc_manager.get_document_by_id(document_id)
        if not document:
            raise HTTPException(status_code=404, detail="文档不存在")

        # 获取文档的所有对话
        from db.models import Conversation

        conversations = session.query(Conversation).filter(Conversation.document_id == document_id).order_by(Conversation.updated_at.desc()).all()

        return [
            {
                "id": conv.id,
                "title": conv.title,
                "created_at": str(conv.created_at),
                "updated_at": str(conv.updated_at),
            }
            for conv in conversations
        ]
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取对话列表失败: {str(e)}")
    finally:
        session.close()


@router.post("/document/{document_id}", response_model=ConversationResponse)
async def create_conversation(
    document_id: int,
    conversation: ConversationCreate,
    doc_manager=Depends(get_document_manager),
):
    """为指定文档创建新对话"""
    try:
        # 创建新对话
        session = doc_manager.db.connect()

        # 检查文档是否存在
        document = doc_manager.get_document_by_id(document_id)
        if not document:
            raise HTTPException(status_code=404, detail="文档不存在")

        from db.models import Conversation

        new_conversation = Conversation(
            document_id=document_id,
            title=conversation.title or "新对话",
            created_at=datetime.now(),
            updated_at=datetime.now(),
        )
        session.add(new_conversation)
        session.commit()
        session.refresh(new_conversation)

        return {
            "id": new_conversation.id,
            "title": new_conversation.title,
            "created_at": str(new_conversation.created_at),
            "updated_at": str(new_conversation.updated_at),
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"创建对话失败: {str(e)}")
    finally:
        session.close()


@router.get("/{conversation_id}/messages", response_model=List[MessageResponse])
async def get_conversation_messages(conversation_id: int, doc_manager=Depends(get_document_manager)):
    """获取指定对话的所有消息"""
    try:
        session = doc_manager.db.connect()
        from db.models import Conversation

        conversation = session.query(Conversation).filter(Conversation.id == conversation_id).first()

        if not conversation:
            raise HTTPException(status_code=404, detail="对话不存在")

        # 获取对话的所有消息
        return [
            {
                "id": msg.id,
                "role": msg.role,
                "content": msg.content,
                "created_at": str(msg.created_at),
            }
            for msg in conversation.messages
        ]
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取消息列表失败: {str(e)}")
    finally:
        session.close()


@router.post("/{conversation_id}/messages", response_model=MessageResponse)
async def send_message(
    conversation_id: int,
    message: MessageCreate,
    doc_manager=Depends(get_document_manager),
):
    """发送消息并获取AI回复"""
    try:
        session = doc_manager.db.connect()
        from db.models import Conversation, Message, Document

        # 检查对话是否存在
        conversation = session.query(Conversation).filter(Conversation.id == conversation_id).first()
        if not conversation:
            raise HTTPException(status_code=404, detail="对话不存在")

        # 获取关联的文档内容
        document = session.query(Document).filter(Document.id == conversation.document_id).first()
        if not document:
            raise HTTPException(status_code=404, detail="关联的文档不存在")

        # 保存用户消息
        user_message = Message(
            conversation_id=conversation_id,
            role="user",
            content=message.content,
            created_at=datetime.now(),
        )
        session.add(user_message)
        session.commit()
        session.refresh(user_message)

        # 准备上下文：文档标题 + 文档内容 + 对话历史
        context = f"文档标题：\n{document.title}\n\n" + f"文档内容：\n{document.content}\n\n" + f"对话历史：\n"

        # 获取对话历史（最近的几条消息）
        history_messages = (
            session.query(Message)
            .filter(Message.conversation_id == conversation_id)
            .order_by(Message.created_at.desc())
            .limit(5)  # 只取最近5条消息作为上下文
            .all()
        )

        # 按时间顺序添加对话历史（旧到新）
        for msg in reversed(history_messages):
            context += f"{msg.role}: {msg.content}\n"

        # 添加当前用户消息
        context += f"user: {message.content}\n"

        # 准备提示词
        prompt = f"你是一个智能助手，需要根据提供的文档内容和对话历史来回答用户的问题，请基于文档内容进行回答。\n\n{context}\nassistant:"

        # 获取AI回复
        try:
            # 统一通过model_loader获取LLM响应，model_loader会根据API_TYPE选择合适的方式
            assistant_reply = model_loader.generate_llm_response(prompt)
        except Exception as e:
            print(f"调用LLM失败: {e}")
            assistant_reply = "抱歉，我现在无法回答您的问题。请稍后再试。"

        # 保存AI回复
        assistant_message = Message(
            conversation_id=conversation_id,
            role="assistant",
            content=assistant_reply,
            created_at=datetime.now(),
        )
        session.add(assistant_message)

        # 更新对话的更新时间
        conversation.updated_at = datetime.now()

        session.commit()
        session.refresh(assistant_message)

        return {
            "id": assistant_message.id,
            "role": assistant_message.role,
            "content": assistant_message.content,
            "created_at": str(assistant_message.created_at),
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"发送消息失败: {str(e)}")
    finally:
        session.close()


@router.delete("/{conversation_id}")
async def delete_conversation(conversation_id: int, doc_manager=Depends(get_document_manager)):
    """删除指定对话"""
    try:
        session = doc_manager.db.connect()
        from db.models import Conversation

        # 查找对话
        conversation = session.query(Conversation).filter(Conversation.id == conversation_id).first()
        if not conversation:
            raise HTTPException(status_code=404, detail="对话不存在")

        # 删除对话及其所有消息
        session.delete(conversation)
        session.commit()

        return {"message": "对话删除成功"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"删除对话失败: {str(e)}")
    finally:
        session.close()


@router.put("/{conversation_id}/title")
async def update_conversation_title(
    conversation_id: int,
    title: str = Body(..., embed=True),
    doc_manager=Depends(get_document_manager),
):
    """更新对话标题"""
    try:
        session = doc_manager.db.connect()
        from db.models import Conversation

        # 查找对话
        conversation = session.query(Conversation).filter(Conversation.id == conversation_id).first()
        if not conversation:
            raise HTTPException(status_code=404, detail="对话不存在")

        # 更新标题
        conversation.title = title
        conversation.updated_at = datetime.now()

        session.commit()

        return {"message": "对话标题更新成功", "title": title}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"更新对话标题失败: {str(e)}")
    finally:
        session.close()
